/*
 * Main.cpp
 * Execution starts here as this file contains the main function
 * - initializes the RayTracer object
 * - calls RayTracer functions to initialize and then render the scene
 * - makes calls to have the returned pixel information output to file
 *
 * @version 	1.00 Feb 2011
 * @author 		Eric Stock
 */

#define WIN32_LEAN_AND_MEAN
#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sstream>
#include <string>
#include <windows.h> 
#include "ImageLoader.h"
#include "Utility.h"
#include "RayTracer.h"
#include <windows.h>
#include <process.h>

#include <GL/glut.h>

Pics * image;
RayTracer tracer;
void TraceScene();
int screenWidth, screenHeight;

LARGE_INTEGER ticksPerSecond;
LARGE_INTEGER tick;   // A point in time
LARGE_INTEGER lastTime;
LARGE_INTEGER time;   // For converting tick into real time

HANDLE threads[3];
HANDLE thread2;
HANDLE thread3;

RayTracer::ThreadArgs args;
RayTracer::ThreadArgs args2;
RayTracer::ThreadArgs args3;

// Called to draw scene
void RenderScene(void)
{
	static int frameCount = 0;

	// Clear the window with current clearing color
	glClear(GL_COLOR_BUFFER_BIT);
	
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	
	image = tracer.RayTracer::GetImage();
	
	glDrawPixels(screenWidth, screenHeight, GL_RGB, GL_FLOAT, image);

	// Flush drawing commands and swap
	glutSwapBuffers();
	
	//tracer.NextFrame();
	
	if(frameCount % 3 == 0) {
	  // get the high resolution counter's accuracy
	  QueryPerformanceFrequency(&ticksPerSecond);

	  // what time is it?
	  QueryPerformanceCounter(&tick);
		
	   
	  LONGLONG elapsed = tick.QuadPart - lastTime.QuadPart;
	  double time = (double)elapsed / (double)ticksPerSecond.QuadPart / 3.0;
	  printf("fps is %f\n",1.0/(flt)time);
	  
	  lastTime = tick;
	}
  TraceScene();
  glFlush();
  frameCount++;
}

///////////////////////////////////////////////////////////
// Set up the rendering state
void SetupRC(void)
{
	glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
}

void TraceScene()
{
	/*args.tPtr = &tracer;
	args.scanLineId = 0;

	threads[0] = (HANDLE) _beginthread( RayTracer::LaunchThread, 0, (void*)&args);

	RayTracer::ThreadArgs args2;
	args2.tPtr = &tracer;
	args2.scanLineId = 1;


	threads[1] = (HANDLE) _beginthread( RayTracer::LaunchThread, 0, (void*)&args2 );

	
	args3.tPtr = &tracer;
	args3.scanLineId = 2;

	threads[2] = (HANDLE) _beginthread( RayTracer::LaunchThread, 0, (void*)&args3 );
	WaitForMultipleObjects(3,threads, true, 1000);//, QS_ALLEVENTS);
	*/
	tracer.IntersectScene(0);
	glutPostRedisplay();
}

int main(int argc,char **argv) {

	// initialize the ray tracer object with the name of the .dat file containing scene info //

	tracer.IntitializeScene();		

	// set up the primary rays //
	tracer.RayTracer::GenScreenDirections();

	//tracer.TestRandomHemisphereVector();
	
	screenHeight = tracer.RayTracer::GetHeight();
	screenWidth = tracer.RayTracer::GetWidth();

	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(screenWidth,screenHeight);
	glutCreateWindow("Simple");

	glutDisplayFunc(RenderScene);   

	SetupRC();
	//TraceScene();
	
	glutMainLoop();

	ImageLoader loader;

	// write the image to file //
	const char* outputFile = "output/output.bmp";
	loader.WriteFile(outputFile, screenWidth, screenHeight, image);
	printf("no sphere intersection is %d\n",RayTracer::noSphereIntersections);
	printf("done\n");
}
